#ifndef ARC_H
#define ARC_H

#include <QDataStream>
#include <QString>

class QDataStream;
class QString;

template <typename T>
class Arc {
  template <typename Y>
  friend QDataStream& operator<<(QDataStream& out, const Arc<Y>& arc);
  template <typename Y>
  friend QDataStream& operator>>(QDataStream& in, Arc<Y>& summit);

  public:
    // Publics Methods
    Arc() {}
    Arc(int source, int destination, const T& info = 1, const QString& name = ""): source(source),
      destination(destination), info(info), name(name) {}
    int getSource() const;
    void setSource(int source);
    int getDestination() const;
    void setDestination(int destination);
    const T& getInfo() const;
    void setInfo(const T& source);
    const QString& getName() const;
    void setName(const QString& name);

  private:
    // Privates Attributes
    int source, destination;
    T info;
    QString name;
};

// Getter for source attribute
template <typename T>
int Arc<T>::getSource() const {
  return source;
}

// Setter for source attribute
template <typename T>
void Arc<T>::setSource(int source) {
  this->source = source;
}

// Getter for destination attribute
template <typename T>
int Arc<T>::getDestination() const {
  return destination;
}

// Setter for destination attribute
template <typename T>
void Arc<T>::setDestination(int destination) {
  this->destination = destination;
}

// Getter for info attribute
template <typename T>
const T& Arc<T>::getInfo() const {
  return info;
}

// Setter for info attribute
template <typename T>
void Arc<T>::setInfo(const T& info) {
  this->info = info;
}

// Getter for name attribute
template <typename T>
const QString& Arc<T>::getName() const {
  return name;
}

// Setter for name attribute
template <typename T>
void Arc<T>::setName(const QString& name) {
  this->name = name;
}

// Operator << for serialization (writing)
template <typename T>
QDataStream& operator<<(QDataStream& out, const Arc<T>& arc) {
  out << arc.source << arc.destination << arc.info << arc.name;
  return out;
}

// Operator >> for serialization (reading)
template <typename T>
QDataStream& operator>>(QDataStream& in, Arc<T>& arc) {
  return in >> arc.source >> arc.destination >> arc.info >> arc.name;
}

#endif
